package HashBuck;

public class HashBuck<K, V> {
    public Node<K, V>[] nodeArray;

    public HashBuck() {
        this.nodeArray = (Node<K, V>[]) new Node[10];
    }

    public int usedSize;

    public static final double DEFAULT_LOAD_FACTOR = 0.75f;

    public void push(K key, V val) {
        int index = key.hashCode() % nodeArray.length;

        Node<K, V> newNode = new Node<>(key, val);

        Node<K, V> curNode = nodeArray[index];

        while (curNode != null) {
            if (curNode.key.equals(key)) {
                curNode.val = val;
                return;
            }
            curNode = curNode.nextNode;
        }

        newNode.nextNode = nodeArray[index];
        nodeArray[index] = newNode;
        this.usedSize++;

        if (doLoadFactor() >= DEFAULT_LOAD_FACTOR) {
            resize();
        }
    }

    private double doLoadFactor() {
        return this.usedSize % nodeArray.length;
    }

    private void resize() {
        Node<K, V>[] newNodeArray = (Node<K, V>[]) new Node[2 * nodeArray.length];
        int newLen = newNodeArray.length;

        for (int i = 0; i < nodeArray.length; i++) {
            Node<K, V> curNode = nodeArray[i];

            while (curNode != null) {
                int newIndex = curNode.key.hashCode() % newLen;
                Node<K, V> next = curNode.nextNode;
                curNode.nextNode = newNodeArray[newIndex];
                newNodeArray[newIndex] = curNode;
                curNode = next;
            }
        }

        nodeArray = newNodeArray;
    }

    public V getVal(K key) {
//        for (int i = 0; i < nodeArray.length; i++) {
//            Node<K, V> curNode = nodeArray[i];
//
//            while (curNode != null) {
//                if (curNode.key.equals(key)) {
//                    return curNode.val;
//                }
//                curNode = curNode.nextNode;
//            }
//        }
//
//        return null;

        int index = key.hashCode() % nodeArray.length;
        Node<K, V> curNode = nodeArray[index];

        while (curNode != null) {
            if (curNode.key.equals(key)) {
                return curNode.val;
            }
            curNode = curNode.nextNode;
        }

        return null;
    }
}
